<template>
  <div class="audition247">
    <p>手写forEach</p>
    <v-md-preview :text="text1" />
    <p>手写map</p>
    <p>与forEach不同的是，map是有返回值的，所以在最后要return一个值</p>
    <v-md-preview :text="text2" />
    <p>手写some</p>
    <p>some是用来查询数组内是否有满足条件的值，如果有，就返回true,后续的元素就不做检查了；否则返回false 。some不会检查空数组</p>
    <p>some有两个参数，callback和要返回的值</p>
    <v-md-preview :text="text3" />
    <p>手写every</p>
    <p>every是检查数组中的元素是否都满足某个条件，如果都满足，就返回true。如果有一个不满足，就返回false</p>
    <v-md-preview :text="text4" />
    <p>手写filter</p>
    <p>检查数组中所有元素，得到所有满足条件的元素，并把这些元素作为新数组返回</p>
    <v-md-preview :text="text5" />
    <p>手写reduce，数组的累加函数，返回值是数组的累加结果</p>
    <v-md-preview :text="text6" />
  </div>
</template>

<script>
const prefix = '``` js'
const suffix = '```'
export default {
  name: 'Audition247',
  data() {
    return {
      text1: `${prefix}
      Array.prototype._forEach = function (cb, newThis) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if(typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 遍历调用者
        for(let i = 0; i < this.length; i++) {
          // newThis是forEach的第二个参数，用来改变this指向的，一般不用
          // 后面三个参数依次对应forEach中的 item index arr
          cb.call(newThis, this[i], i, this)
        }
      }
      \n${suffix}`,
      text2: `${prefix}
      Array.prototype._map = function (cb, newThis) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if (typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 创建一个空的新数组
        let newArr = []
        // 生成新数组中的每个元素
        for(let i = 0; i < this.length; i++) {
          newArr.push(cb.call(newThis, this[i], i, this))
        }
        // 返回新数组
        return newArr
      }
      \n${suffix}`,
      text3: `${prefix}
      Array.prototype._some = function (cb) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if (typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 初始化查询结果
        let result = false
        for(let i = 0; i < this.length; i++) {
          // 如果查询到了 就返回true 并跳出遍历
          if(cb(this[i], i, this)) {
            result = true
            break
          }
        }
        return result
      }
      \n${suffix}`,
      text4: `${prefix}
      Array.prototype._every = function (cb) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if (typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 初始化检查结果
        let result = true
        for(let i = 0; i < this.length; i++) {
          // 如果有不满足条件的，就返回false，并跳出循环
          if(!cb(this[i], i, this)) {
            result = false
            break
          }
        }
        return result
      }
      \n${suffix}`,
      text5: `${prefix}
      Array.prototype._filter = function (cb) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if (typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 初始化新数组
        let newArr = []
        for(let i = 0; i < this.length; i++) {
          // 如果满足条件，就放入newArr
          cb(this[i], i, this)  && newArr.push(this[i])
        }
        // 返回新数组
        return newArr
      }
      \n${suffix}`,
      text6: `${prefix}
      Array.prototype._reduce = function (cb, initValue) {
        // 如果调用者不是数组 就抛出错误
        if (!Array.isArray(this)) {
          throw Error(this + 'is not a array')
        }
        // 如果cb不是回调函数，就抛出错误
        if (typeof cb !== 'function') {
          throw Error(Object.prototype.toString.call(cb) + 'is not a function')
        }
        // 定义初始值 如果写了初始值，就用初始值，如果没写，就拿数组第一个值做初始值
        var total = initValue || this[0]
        for(let i = initValue ? 0 : 1; i < this.length; i++) {
          total = cb(total, this[i], i, this)
        }
        return total
      }
      \n${suffix}`,
    }
  }
}
</script>

<style>

</style>